﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using MIAP.Entidades.TiposXML;

namespace MIAP.Negocio.Utiles
{
    public class LecturaXML
    {
        #region Variables

        /// <summary>
        /// Objeto para el manejo de archivos de XML.
        /// </summary>
        private XmlDocument xmlDocument;

        #endregion

        #region Constantes

        /// <summary>
        /// Nombre de la propiedad ColumnaExcel del archivo XML.
        /// </summary>
        private const string ColumnaExcel = "IndiceColumna";

        /// <summary>
        /// Nombre de la propiedad NombreTemplate del archivo XML.
        /// </summary>
        private const string NombreColumna = "NombreColumna";

        /// <summary>
        /// Nombre de la propiedad TipoVariable del archivo XML.
        /// </summary>
        private const string TipoVariableAtr = "TipoDato";

        /// <summary>
        /// Nombre de la propiedad NombreHoja del archivo XML.
        /// </summary>
        public const string NombreHoja = "NombreHoja";

        /// <summary>
        /// Nombre de la propiedad FormatoNombre del archivo XML.
        /// </summary>
        public const string FormatoNombre = "FormatoNombre";

        /// <summary>
        /// nombre del Tag para obtener una columna del archivo excel
        /// </summary>
        private const string TagColumnaExcel = "ColumnaExcel";

        /// <summary>
        /// nombre del Tag para obtener una columna del archivo de textp
        /// </summary>
        private const string TagColumnaTexto = "ColumnaTexto";

        /// <summary>
        /// nombre del Tag para obtener una columna del archivo
        /// </summary>
        private const string TagExcel = "ArchivoExcel";

        #region archivo texto
        /// <summary>
        /// nombre del Tag para obtener una columna del archivo
        /// </summary>
        private const string TagText = "ArchivoTexto";


        /// <summary>
        /// Nombre de la propiedad Separador del archivo XML para los archivos de texto.
        /// </summary>
        public const string Separador = "Separador";


        #endregion

        #endregion

        #region Constructores

        /// <summary>
        /// Constructor 
        /// </summary>
        public LecturaXML(Stream archivoXml)
        {
            xmlDocument = new XmlDocument();
            xmlDocument.Load(archivoXml); 
        }

        /// <summary>
        /// Constructor 
        /// </summary>
        public LecturaXML(string archivoXml)
        {
            xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(archivoXml);
        }

        #endregion

        #region Metodos

        #region Metodos Archivo Texto

        /// <summary>
        ///  Metodo encargado de regresar el valor del atributo Separador en el archivo XML para los archivos de texto.
        /// </summary>
        /// <returns>Valor del atributo.</returns>
        public string ObtenValorAtributoTextSeparador()
        {
            return ObtenValorAtributoText(Separador);
        }


        /// <summary>
        /// Metodo encargado de regresar el valor del archivo XML para los archivos de texto.
        /// </summary>
        /// <param name="nombreAtributo">Nombre del atributo a buscar.</param>
        /// <returns>Valor del atributo.</returns>
        private string ObtenValorAtributoText(string nombreAtributo)
        {
            return ObtenerValorXML(TagText, nombreAtributo);
        }

        #endregion



        /// <summary>
        /// Metodo encargado de regresar el valor del archivo XML.
        /// </summary>
        /// <param name="nombreAtributo">Nombre del atributo a buscar.</param>
        /// <returns>Valor del atributo.</returns>
        public string ObtenValorAtributoExcel(string nombreAtributo)
        {
             return ObtenerValorXML(TagExcel, nombreAtributo);
        }

        /// <summary>
        /// Metodo encargado de regresar el valor del archivo XML.
        /// </summary>
        /// <param name="nombreTag">Nombre del tag.</param>
        /// <param name="nombreAtributo">Nombre del atributo a buscar.</param>
        /// <returns>Valor del atributo.</returns>
        private string ObtenerValorXML(string nombreTag, string nombreAtributo)
        {
            var valorAtributo = string.Empty;
            var atributos = xmlDocument.GetElementsByTagName(nombreTag);
            foreach (XmlElement nodo in atributos)
            {
                valorAtributo = nodo.GetAttribute(nombreAtributo);
            }

            return valorAtributo;
        }

        /// <summary>
        /// Metodo encargado de btener los atributos de todas las columnas en el excel
        /// </summary>
        /// <returns>Valor del atributo.</returns>
        public List<ColumnaExcel> ObtenerValorColumnasExcelXML()
        {
            var atributos = xmlDocument.GetElementsByTagName(TagColumnaExcel);

            return (from XmlElement nodo in atributos
                    select new ColumnaExcel
                        {
                            IndiceColumna = nodo.GetAttribute(ColumnaExcel), 
                            NombreColumna = nodo.GetAttribute(NombreColumna),
                            TipoVariable = this.GetTipoVariable(nodo.GetAttribute(TipoVariableAtr))
                        }).ToList();
        }

        /// <summary>
        /// Metodo encargado de btener los atributos de todas las columnas en el excel
        /// </summary>
        /// <returns>Valor del atributo.</returns>
        public List<ColumnaBase> ObtenerValorColumnasTextoXML()
        {
            var atributos = xmlDocument.GetElementsByTagName(TagColumnaTexto);

            return (from XmlElement nodo in atributos
                    select new ColumnaBase
                        {
                            TipoVariable = this.GetTipoVariable(nodo.GetAttribute(TipoVariableAtr))
                        }).ToList();
        }

        /// <summary>
        /// obtiene un valor del enum TipoVariable a partir de un string
        /// </summary>
        /// <param name="atribute"></param>
        /// <returns></returns>
        private TipoVariable GetTipoVariable(string atribute)
        {
            var nNumeric = Enum.GetName(typeof(TipoVariable), TipoVariable.Numeric);
            var nBoolean = Enum.GetName(typeof(TipoVariable), TipoVariable.Boolean);
            var nString = Enum.GetName(typeof (TipoVariable), TipoVariable.String);
            if (atribute.ToLower().Equals(nNumeric.ToLower()))
            {
                return TipoVariable.Numeric;
            }
            if (atribute.ToLower().Equals(nBoolean.ToLower()))
            {
                return TipoVariable.Boolean;
            }
            if (atribute.ToLower().Equals(nString.ToLower()))
            {
                return TipoVariable.String;
            }
            return TipoVariable.String;
        }

        #endregion
    }
}
